﻿using RakutenProxy.Model.NopCommerce;
using RakutenProxy.Model.Rakuten;
using System;
using System.Data.Entity;
using System.Linq;

namespace RakutenProxy.DataConverter
{
    public class RakNopProductProductAttributeMappingConverter : RakNopDataConverter<RakutenProxy.Model.Rakuten.Product_ProductAttribute_Mapping, RakutenProxy.Model.NopCommerce.Product_ProductAttribute_Mapping>
    {
        public RakNopProductProductAttributeMappingConverter(DbContext sourceDbContext, DbContext targetDbContext)
            : base(sourceDbContext, targetDbContext)
        {
        }

        protected override Model.NopCommerce.Product_ProductAttribute_Mapping GetObjectFromSource(Model.Rakuten.Product_ProductAttribute_Mapping source)
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var mapping = new Model.NopCommerce.Product_ProductAttribute_Mapping();
            var productMap = rakDbContext.Rakuten_NopCommerce_Product_Maps.FirstOrDefault(m => m.RakutenProductId == source.ProductId);
            var attributeMap = rakDbContext.Rakuten_NopCommerce_ProductAttribute_Maps.FirstOrDefault(m => m.RakutenProductAttributeId == source.ProductAttributeId);

            if (productMap == null || attributeMap == null)
                throw new ArgumentException("Mapping not found", "source");

            mapping.AttributeControlTypeId = (int)source.ControlTypeId;
            mapping.ProductId = productMap.NopCommerceProductId;
            mapping.ProductAttributeId = attributeMap.NopCommerceProductAttributeId;
            mapping.IsRequired = true;

            return mapping;
        }

        protected override void UpdateObjectFromSource(Model.NopCommerce.Product_ProductAttribute_Mapping target, Model.Rakuten.Product_ProductAttribute_Mapping source)
        {
            // The mapping is no need to update, if needed, the product or product attribute will update themselves
        }

        public override void Migrate()
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var nopDbContext = (NopCommerceEntities)TargetContext;

            var ids = rakDbContext.Product_ProductAttribute_Mappings.Select(p => p.Id);
            MigrateManyRecords(ids);

            //var mappedIds = rakDbContext.Rakuten_NopCommerce_Product_ProductAttributeMapping_Maps.Select(m => m.Rakuten_Product_ProductAttribute_Mapping_Id);
            //var notMapped = rakDbContext.Product_ProductAttribute_Mappings.Where(m => !mappedIds.Contains(m.Id));
            //var mapped = rakDbContext.Product_ProductAttribute_Mappings.Except(notMapped);

            //foreach (var map in notMapped)
            //{
            //    var nopMap = GetObjectFromSource(map);
            //    nopDbContext.Product_ProductAttribute_Mapping.Add(nopMap);
            //    nopDbContext.SaveChanges();
            //    var nopRakMap = new Rakuten_NopCommerce_Product_ProductAttributeMapping_Map { Nop_Product_ProductAttribute_Mapping_Id = nopMap.Id, Rakuten_Product_ProductAttribute_Mapping_Id = map.Id };
            //    rakDbContext.Rakuten_NopCommerce_Product_ProductAttributeMapping_Maps.Add(nopRakMap);
            //}

            //rakDbContext.SaveChanges();
            //nopDbContext.SaveChanges();
        }

        public override void MigrateOneRecord(int id)
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var nopDbContext = (NopCommerceEntities)TargetContext;

            var productMappedRecord = rakDbContext.Product_ProductAttribute_Mappings.FirstOrDefault(m => m.Id == id);
            if (productMappedRecord == null)
                return;

            var map = rakDbContext.Rakuten_NopCommerce_Product_ProductAttributeMapping_Maps.FirstOrDefault(m => m.Rakuten_Product_ProductAttribute_Mapping_Id == id);
            
            if (map == null)
            {
                var nopMap = GetObjectFromSource(productMappedRecord);
                nopDbContext.Product_ProductAttribute_Mapping.Add(nopMap);
                nopDbContext.SaveChanges();

                var nopRakMap = new Rakuten_NopCommerce_Product_ProductAttributeMapping_Map { Nop_Product_ProductAttribute_Mapping_Id = nopMap.Id, Rakuten_Product_ProductAttribute_Mapping_Id = productMappedRecord.Id };
                rakDbContext.Rakuten_NopCommerce_Product_ProductAttributeMapping_Maps.Add(nopRakMap);
                rakDbContext.SaveChanges();
            }
        }

        public override void RemoveOneRecord(int id)
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var nopDbContext = (NopCommerceEntities)TargetContext;

            var map = rakDbContext.Rakuten_NopCommerce_Product_ProductAttributeMapping_Maps.FirstOrDefault(m => m.Rakuten_Product_ProductAttribute_Mapping_Id == id);
            if (map == null)
                return;

            var nopAttributeMapping = nopDbContext.Product_ProductAttribute_Mapping.FirstOrDefault(m => m.Id == map.Nop_Product_ProductAttribute_Mapping_Id);
            if (nopAttributeMapping != null)
            {
                nopDbContext.Product_ProductAttribute_Mapping.Remove(nopAttributeMapping);
            }

            rakDbContext.Rakuten_NopCommerce_Product_ProductAttributeMapping_Maps.Remove(map);

            rakDbContext.SaveChanges();
            nopDbContext.SaveChanges();
        }
    }
}